package org.fast.develop.logicflow.management.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import org.fast.develop.logicflow.management.core.EventBus;
import org.fast.develop.logicflow.management.bo.LogicBytearrayBo;
import org.fast.develop.logicflow.management.bo.LogicDefinitionBo;
import org.fast.develop.logicflow.management.bo.LogicDeploymentBo;
import org.fast.develop.logicflow.management.bo.LogicModelBo;
import org.fast.develop.logicflow.management.builder.CreateDeploymentBuilder;
import org.fast.develop.logicflow.management.core.event.DeployedEvent;
import org.fast.develop.logicflow.management.exception.LogicException;
import org.fast.develop.logicflow.repository.domain.bytearray.LogicBytearray;
import org.fast.develop.logicflow.repository.domain.bytearray.LogicBytearrayRepository;
import org.fast.develop.logicflow.repository.domain.definition.LogicDefinition;
import org.fast.develop.logicflow.repository.domain.definition.LogicDefinitionRepository;
import org.fast.develop.logicflow.repository.domain.deployment.LogicDeployment;
import org.fast.develop.logicflow.repository.domain.deployment.LogicDeploymentRepository;
import org.fast.develop.logicflow.repository.domain.model.LogicModel;
import org.fast.develop.logicflow.repository.domain.model.LogicModelRepository;
import org.fast.develop.logicflow.management.service.LogicRepositoryService;

import java.util.Date;

/**
 * @author 莫寅
 * @createTime 2022-12-20 02:51
 * @desc：
 */
public class RepositoryServiceImpl implements LogicRepositoryService {


    private LogicDeploymentRepository logicDeploymentRepository;
    private LogicDefinitionRepository logicDefinitionRepository;
    private LogicModelRepository logicModelRepository;
    private LogicBytearrayRepository logicBytearrayRepository;
    private EventBus eventBus;

    public RepositoryServiceImpl(
            LogicDeploymentRepository logicDeploymentRepository,
            LogicDefinitionRepository logicDefinitionRepository,
            LogicModelRepository logicModelRepository,
            LogicBytearrayRepository logicBytearrayRepository,
            EventBus eventBus
    ) {
        this.eventBus = eventBus;
        this.logicDeploymentRepository = logicDeploymentRepository;
        this.logicDefinitionRepository = logicDefinitionRepository;
        this.logicModelRepository = logicModelRepository;
        this.logicBytearrayRepository = logicBytearrayRepository;
    }

    @Override
    public CreateDeploymentBuilder createDeployment() {
        return new CreateDeploymentBuilder(this);
    }

    @Override
    public LogicDeployment deploy(CreateDeploymentBuilder createDeploymentBuilder) {
        byte[] bytes = null;
        String key = createDeploymentBuilder.getKey();
        String name = createDeploymentBuilder.getName();
        String category = createDeploymentBuilder.getCategory();

        //创建发布
        LogicDeploymentBo logicDeploymentBo = new LogicDeploymentBo();
        logicDeploymentBo.setName(name);
        logicDeploymentBo.setKey(key);
        logicDeploymentBo.setCategory(category);
        logicDeploymentBo.setDeployTime(new Date());
        LogicDeployment logicDeployment = logicDeploymentRepository.save(logicDeploymentBo);

        //模型表中设置发布ID
        if(StrUtil.isNotBlank(createDeploymentBuilder.getModelId())){
            LogicModel logicModel = logicModelRepository.get(createDeploymentBuilder.getModelId());
            LogicModelBo logicModelBo = BeanUtil.copyProperties(logicModel, LogicModelBo.class);
            logicModelBo.setDeploymentId((String) logicDeployment.getId());
            logicModelRepository.save(logicModelBo);


            bytes = logicBytearrayRepository.get(logicModel.getResourceId()).getBytes();
        }else{
            bytes = createDeploymentBuilder.getBytes();
        }

        if(bytes == null){
            throw new LogicException("bytes is not be null!");
        }

        //生成标准定义bytes
        byte[] definitionBytes = createDefinitionBytes(bytes);
        String bytearrayName = createDeploymentBuilder.getKey() + "_" + createDeploymentBuilder.getName() + ".json";
        //创建文件
        LogicBytearrayBo logicBytearrayBo = new LogicBytearrayBo();
        logicBytearrayBo.setName(bytearrayName);
        logicBytearrayBo.setBytes(definitionBytes);
        LogicBytearray logicBytearray = logicBytearrayRepository.save(logicBytearrayBo);

        //获取版本号
        LogicDefinition logicDefinition = logicDefinitionRepository.findByMaxVersion(key);
        int version = 0;
        if(logicDefinition != null){
            version = logicDefinition.getVersion() + 1;
        }else{
            version += 1;
        }


        //创建定义
        LogicDefinitionBo logicDefinitionBo = new LogicDefinitionBo();
        logicDefinitionBo.setCategory(category);
        logicDefinitionBo.setKey(key);
        logicDefinitionBo.setName(name);
        logicDefinitionBo.setDeploymentId((String) logicDeployment.getId());
        logicDefinitionBo.setResourceId((String) logicBytearray.getId());
        logicDefinitionBo.setVersion(version);
        logicDefinitionRepository.save(logicDefinitionBo);

        //删除key所在的删除
        DeployedEvent deployedEvent = new DeployedEvent(logicDeployment);
        eventBus.publishEvent(deployedEvent);
        return logicDeployment;
    }



    /**
     * TODO 将模型schema生成标准定义
     * @param bytes
     * @return
     */
    private byte[] createDefinitionBytes(byte[] bytes){
        return bytes;
    }
}
